public with sharing class Callidus_DoNotAcceptVF 
{
    public String reason {get; set;}
    public Sales_Contract__c salesContract {get; set;}
    public String statusUpdatedFlag {get; set;}
    private Sales_Contract__c[] scList {get; set;}
    private String sId  {get; set;}     
    private Map<String, Schema.SObjectField> scSObjectFieldMap = new Map<String, Schema.SObjectField>(); 
    private String constructSoql {get; set;}
    private DataAccessControlUtil dacu = null;

    public Callidus_DoNotAcceptVF()
    {
        sId = ApexPages.currentPage().getParameters().get('sId');
        dacu = new DataAccessControlUtil();
        
        SObject scObj = new Sales_Contract__c();
        String message = dacu.isUpdateableObjectByUser(scObj);
        Sales_Contract__c[] sContract = null;
        
        if(message.equalsIgnoreCase('success'))
        {       
            if(scSObjectFieldMap.isEmpty())
                scSObjectFieldMap = dacu.getFieldMap(scObj);
            
            String[] expectedFields = new String[]{'Id','Status__c', 'Employee_Reject_Reason__c', 'Reject_Reason__c'}; 
            Set<String> allowedFields = dacu.getAccessibleFields(scObj, scSObjectFieldMap, expectedFields);
    
            if(!allowedFields.isEmpty())
            {
                constructSoql = 'Select ';
                for(String roField: allowedFields)
                {
                    constructSoql += roField+', ';
                }
                constructSoql = constructSoql.substring(0, constructSoql.length() - 2);
                constructSoql += ' from Sales_Contract__c s where s.Id = :sId ';

                sContract = Database.query(constructSoql);
                scList = sContract;
                salesContract = sContract[0];
            }
        }       
    }

    public PageReference saveReason()
    {
    	if(salesContract.Employee_Reject_Reason__c == null)
    	{
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.error, 'Select Reject Reason..'));
            return null;
    	}
    	
        if(reason.trim().length() == 0)
        {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.error, 'Enter the Rejection Comment.'));
            return null;
        }

        dacu = new DataAccessControlUtil();
        SObject scObj = new Sales_Contract__c();
        String message = dacu.isUpdateableObjectByUser(scObj);

        if(message.equalsIgnoreCase('success'))
        {       
            if(scList.size() > 0)
            {
                scList[0].Reject_Reason__c = reason;
                scList[0].Employee_Reject_Reason__c = salesContract.Employee_Reject_Reason__c;
            }
                
            update scList;
            statusUpdatedFlag = 'true';
            updateStatusToRejected();
        }       
        return null;
    }

    private void updateStatusToRejected()
    {
        SObject scObj = new Sales_Contract__c();
        String message = dacu.isUpdateableObjectByUser(scObj);
        Sales_Contract__c[] sContract = null;
        
        if(message.equalsIgnoreCase('success'))
        {       
            if(scSObjectFieldMap.isEmpty())
                scSObjectFieldMap = dacu.getFieldMap(scObj);
            
            String[] expectedFields = new String[]{'Id','Status__c', 'AttachmentIDVals__c', 'OwnerId', 'UserID__c', 'Email_Notification_1__c', 'Email_Notification_2__c', 'Email_Notification_3__c'}; 
            Set<String> allowedFields = dacu.getAccessibleFields(scObj, scSObjectFieldMap, expectedFields);
    
            if(!allowedFields.isEmpty())
            {
                constructSoql = 'Select ';
                for(String roField: allowedFields)
                {
                    constructSoql += roField+', ';
                }
                constructSoql = constructSoql.substring(0, constructSoql.length() - 2);
                constructSoql += ' from Sales_Contract__c s where s.Id = :sId ';

                sContract = Database.query(constructSoql);//[select Status__c, Viewed_Attachment_Name__c, ViewedAttachmentID__c, UserID__c from Sales_Contract__c where id = :sc[0].Id];
                
                scObj = sContract[0];

                //Note: Whenever a new Custom field has to be updated, add it to the below Set.
                Set<String> expectedUpdateableFields = new Set<String>{'Status__c', 'Date_Rejected__c'};
                
                //Store the expected updated fields and their values
                Map<String, Object> fieldsValMap = new Map<String, Object>();
                fieldsValMap.put('Status__c', 'Rejected');
                fieldsValMap.put('Date_Rejected__c', Datetime.now());
                
                //Get the filtered Fields that can be updated
                Set<String> filteredFields = dacu.getFilteredUpdateableFields(scSObjectFieldMap, expectedUpdateableFields);
                
                //Update only fields with update permsission
                for(String s: filteredFields)
                {
                    if(!s.equalsIgnoreCase('Date_Rejected__c'))
                        scObj.put(s, (String)fieldsValMap.get(s));
                    else
                        scObj.put(s, (DateTime)fieldsValMap.get(s));
                    
                }

                if(!filteredFields.isEmpty())   
                {
                    try
                    {   
                        update scObj;


                        String[] attachmentIdList = sContract[0].AttachmentIDVals__c.split(',');
                        String substituteVal = '(';
                        for(String v: attachmentIdList)
                        {
                            substituteVal += '\''+v+'\',';
                        }
                        substituteVal = substituteVal.substring(0, (substituteVal.length() - 1));
                        substituteVal += ')';
                        
                        ESAPI.accessController().setSharingMode(SFDCAccessController.SharingMode.WITHOUT);
                        //fetchAsUser method has the code that checks whether the current User has been granted by the Admin to bypass the sharing rules.  
                        List<SObject> sObjectList = ESAPI.accessController().fetchAsUser('select Body, Id, Name, ContentType from Attachment where id in '+substituteVal);
                        Attachment[] queryAttachment = sObjectList;                                             
                        
                        Messaging.EmailFileAttachment[] allAttachments = new  Messaging.EmailFileAttachment[queryAttachment.size()]; 
                        for(integer i=0;i<queryAttachment.size();i++)
                        {
                            Messaging.EmailFileAttachment fileAttachment = new Messaging.EmailFileAttachment();
                            fileAttachment.setBody(queryAttachment[i].Body);
                            fileAttachment.setFileName(queryAttachment[i].Name);
                            allAttachments[i] =  fileAttachment;
                        }

                        EmailTemplate e = [select Id,Name,Subject,body from EmailTemplate where name like :'Callidus_Plan_Document_Rejected_Mail'];
                        
			            URL__c[] urlList = [select Plan_Doc_Type__c from URL__c limit 1];
                        
                                                           
                        Messaging.SingleEmailMessage[] mailList = new Messaging.SingleEmailMessage[]{};
    
                        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();                 
                        mail.saveAsActivity = false;
			            if(urlList.size() > 0 && urlList[0].Plan_Doc_Type__c == 'no')
			            {
	                        mail.setFileAttachments(allAttachments);
			            }
                        mail.setTargetObjectId(sContract[0].UserId__c);
                        mail.setTemplateId(e.Id);
                        mail.setWhatId(sContract[0].Id);
                        mail.setUseSignature(false);
                        mail.setSaveAsActivity(false);
                        mailList.add(mail);
    
                        mail = new Messaging.SingleEmailMessage();                  
                        mail.saveAsActivity = false;
			            if(urlList.size() > 0 && urlList[0].Plan_Doc_Type__c == 'no')
			            {
	                        mail.setFileAttachments(allAttachments);
			            }
                        mail.setTargetObjectId(sContract[0].OwnerId);
                        mail.setTemplateId(e.Id);
                        mail.setWhatId(sContract[0].Id);
                        mail.setUseSignature(false);
                        mail.setSaveAsActivity(false);
                        mailList.add(mail);
                        
                        if(sContract[0].Email_Notification_1__c != null)
                        {
                            mail = new Messaging.SingleEmailMessage();                  
                            mail.saveAsActivity = false;
				            if(urlList.size() > 0 && urlList[0].Plan_Doc_Type__c == 'no')
				            {
		                        mail.setFileAttachments(allAttachments);
				            }
                            mail.setTargetObjectId(sContract[0].Email_Notification_1__c);
                            mail.setTemplateId(e.Id);
                            mail.setWhatId(sContract[0].Id);
                            mail.setUseSignature(false);
                            mail.setSaveAsActivity(false);
                            mailList.add(mail);
                        }
    
                        if(sContract[0].Email_Notification_2__c != null)
                        {
                            mail = new Messaging.SingleEmailMessage();                  
                            mail.saveAsActivity = false;
				            if(urlList.size() > 0 && urlList[0].Plan_Doc_Type__c == 'no')
				            {
		                        mail.setFileAttachments(allAttachments);
				            }
                            mail.setTargetObjectId(sContract[0].Email_Notification_2__c);
                            mail.setTemplateId(e.Id);
                            mail.setWhatId(sContract[0].Id);
                            mail.setUseSignature(false);
                            mail.setSaveAsActivity(false);
                            mailList.add(mail);
                        }
    
                        if(sContract[0].Email_Notification_3__c != null)
                        {
                            mail = new Messaging.SingleEmailMessage();                  
                            mail.saveAsActivity = false;
				            if(urlList.size() > 0 && urlList[0].Plan_Doc_Type__c == 'no')
				            {
		                        mail.setFileAttachments(allAttachments);
				            }
                            mail.setTargetObjectId(sContract[0].Email_Notification_3__c);
                            mail.setTemplateId(e.Id);
                            mail.setWhatId(sContract[0].Id);
                            mail.setUseSignature(false);
                            mail.setSaveAsActivity(false);
                            mailList.add(mail);
                        }
                        // Send the email
                        Messaging.sendEmail(mailList);
                    }
                    catch(Exception e)
                    {
                        ApexPages.addMessage(new Apexpages.Message(ApexPages.severity.info, e.getMessage()));
                    }
                }
            }
        }
    }

    static testMethod void testGetTemplateAttachmentsVF() 
    {
        
        PageReference pg = Page.DoNotAccept;
        
        Test.setCurrentPage(pg);
        
        Template__c t = new Template__c(name = 'Test12321');
        insert t;
        Template__c[] tempT = [select name from Template__c where id = :t.id];
        system.assertEquals(t.name, tempT[0].name);
        
        try
        {
            Template__c tDup = new Template__c(name = 'Test12321');
            insert tDup;
        }
        catch(Exception e){}

        Attachment a = new Attachment(name = 'Test Attach.doc', Body = Blob.valueOf('<html><body>This is {Attachment}</body></html>'), parentId = t.Id);
        insert a;
        Attachment[] attT = [select name, Body, Parentid from Attachment where id = :a.id];
        system.assertEquals(a.name, attT[0].name);
        system.assertEquals(a.Body.toString(), attT[0].Body.toString());
        system.assertEquals(a.ParentId, attT[0].ParentId);
        
        Attachment a1 = new Attachment(name = 'Test', Body = Blob.valueOf('<html><body>This is {Attachment}</body></html>'), parentId = t.Id);
        insert a1;
        attT = [select name, Body, Parentid from Attachment where id = :a.id];
        system.assertEquals(a.name, attT[0].name);
        system.assertEquals(a.Body.toString(), attT[0].Body.toString());
        system.assertEquals(a.ParentId, attT[0].ParentId);
        
        Sales_Contract__c sc = new Sales_Contract__c(TemplateName__c = t.name, UserID__c = UserInfo.getUserId(), AttachmentID__c = a.id, AttachmentIdVals__c = a.Id, Number_of_Attachments__c = 1, Status__c = 'Viewed', Email_Notification_1__c = UserInfo.getUserId(), Email_Notification_2__c = UserInfo.getUserId(), Email_Notification_3__c = UserInfo.getUserId());
        insert sc;
        Sales_Contract__c[] scT = [select id from Sales_Contract__c where id = :sc.Id];
        system.assertEquals(sc.id, scT[0].id);
        pg.getParameters().put('sId', sc.id);       
        Callidus_DoNotAcceptVF gtvf = new Callidus_DoNotAcceptVF();
        gtvf.updateStatusToRejected();
        gtvf.reason = '';
        gtvf.saveReason();
        gtvf.reason = 'Not Accepted';
        gtvf.saveReason();
    }

    static testMethod void dacuTestCase() 
    {
        DataAccessControlUtil dacu = new DataAccessControlUtil();
        SObject sObj = new CallidusDataSOurce__c();
        Map<String, Schema.Sobjectfield> fieldsMap = dacu.getFieldMap(sObj);
        String[] expectedFieldMap = new String[]{'Id','Name'};
        Set<String> allowedFields = dacu.getAccessibleFields(sObj, fieldsMap, expectedFieldMap);
        Set<String> filteredList = dacu.getFilteredCreateableFields(fieldsMap, allowedFields);
        filteredList = dacu.getFilteredUpdateableFields(fieldsMap, allowedFields);
        system.assertEquals('success', dacu.isCreateableObjectByUser(sObj));
        system.assertEquals('success', dacu.isUpdateableObjectByUser(sObj));
        system.assertEquals('success', dacu.isDeleteableObjectByUser(sObj));
        dacu.pageMessage(sobj, 'create');
        
    }

    
}